using System;
using System.Collections.Generic;
using System.Text;

namespace GPSNav.NET
{
	public struct GeoRectangle
	{
		public static GeoRectangle Empty = new GeoRectangle(0, 0, 0, 0);
		private GeoPoint location;
		public GeoPoint Location
		{
			get { return location; }
			set { location = value; }
		}

		private GeoPoint locationEnd;
		public GeoPoint LocationEnd
		{
			get { return locationEnd; }
			set { locationEnd = value; }
		}

		private GeoSize size;
		public GeoSize Size
		{
			get { return size; }
			set { size = value; }
		}


		public GeoRectangle(double lat, double lon, double width, double height)
		{
			location = new GeoPoint(lat, lon);
			size = new GeoSize(width, height);
			locationEnd = location + size;
		}
		public GeoRectangle(GeoPoint locationStart, GeoPoint locationEnd)
		{
			this.location = locationStart;
			this.locationEnd = locationEnd;
			this.size = locationEnd - locationStart;
		}
		public GeoRectangle(GeoPoint location, GeoSize size)
		{
			this.location = location;
			this.locationEnd = location + size;
			this.size = size;
		}

		public bool Contains(GeoPoint p)
		{

			if (
				(p.Lat >= location.Lat && p.Lat <= location.Lat + size.Width) &&
				(p.Lon >= location.Lon && p.Lon <= location.Lon + size.Height)
				)
			{
				return true;
			}
			return false;
		}


		public bool Contains(GeoRectangle r)
		{
			if (
				(r.location.Lat >= location.Lat && r.location.Lat + r.size.Width <= location.Lat + size.Width) &&
				(r.location.Lon >= location.Lon && r.location.Lon + r.size.Height <= location.Lon + size.Height)
				)
			{
				return true;
			}

			return false;
		}



		public override bool Equals(object obj)
		{
			return base.Equals(obj);
		}
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public static bool operator !=(GeoRectangle r1, GeoRectangle r2)
		{
			return !(r1==r2);
		}
		public static bool operator ==(GeoRectangle r1, GeoRectangle r2)
		{
			return (r1.Location == r2.Location && r1.Size == r2.Size);
		}

		public static GeoPoint Middle(GeoRectangle r1)
		{
			GeoPoint ret = new GeoPoint(r1.LocationEnd.Lat - r1.Location.Lat, r1.LocationEnd.Lon - r1.Location.Lon);
			return ret;
		}

		public GeoPoint Middle()
		{
			return GeoRectangle.Middle(this);
		}

		public static GeoRectangle Intersect(GeoRectangle r1, GeoRectangle r2)
		{


			GeoRectangle ret = GeoRectangle.Empty;
			//ret.Location = new GeoPoint(Math.Max(r1.Location.Lat, r2.Location.Lat), Math.Max(r1.Location.Lon, r2.Location.Lon));
			ret.Location = new GeoPoint(Math.Max(r1.Location.Lat, r2.Location.Lat), Math.Max(r1.Location.Lon, r2.Location.Lon));
			ret.Size = new GeoSize(Math.Min(r1.LocationEnd.Lat - ret.Location.Lat, r2.LocationEnd.Lat - ret.Location.Lat),

				Math.Min(r1.LocationEnd.Lon - ret.Location.Lon, r2.LocationEnd.Lon - ret.Location.Lon));

			if (ret.Size.Width < 0 || ret.Size.Height < 0)
				return GeoRectangle.Empty;

			return ret;


		}


		public override string ToString()
		{
			return String.Format("GeoRectangle {{ Location:{0}, Size:{1} }}", location, size);
		}

	}
}
